package warthog.parsegen;

import warthog.cradle.JavaClass;

/**
 * Represents a particular (possibly abstract) class of semantic node.
 * One or more symbols (both terminal and nonterminal) will be registered
 * with each SemanticClass. The automaton code must respect these declarations.
 * 
 * @author Ian
 *
 */
public class SemanticClass {
	static int nextID=0;
	final int id;
	final String jt;
	//final List<Sym> members = new ArrayList<Sym>();
	SemanticClass(String jt) {
		this.jt = jt;
		id = nextID++;
	}
	String javaType() { return jt; }
	String yys() { return "yys_"+id; }
	String yyStackDecl() {
		return "java.util.Stack<"+jt+"> "+yys()+" = new java.util.Stack<"+jt+">();";
	}
	void writePop(JavaClass cw, int posn) {
		cw.code(jt+" $"+posn+"="+yys()+".pop(); ");
	}
	void writeDeclareHead(JavaClass cw) {
		cw.code(jt+" $$;");
	}
	void writePush(JavaClass cw) {
		cw.code(yys()+".push($$);");
	}
	String yyStackReset() { return ""+yys()+".clear();"; }
	void writeTake(JavaClass cw) {
		cw.code("	public void take(int type, "+javaType()+" $$) throws Error { yy_wants(type, "+id+"); yyShift(yyfindShift(type)); ");
		writePush(cw);
		cw.codeln(" }");
	}
	void writeFinish(JavaClass cw) {
		cw.codeln("	public "+javaType()+" finish() throws Error { yyfindShift(0);return "+yys()+".pop(); }");
	}
	static class VOID extends SemanticClass {
		static final VOID theVOID = new VOID();
		private VOID() { super("void"); }
		void writePop(JavaClass cw, int posn) { }
		void writeDeclareHead(JavaClass cw) { }
		void writePush(JavaClass cw) { }
		String javaType() { return "void"; }
		String yyStackDecl() { return ""; }
		String yyStackReset() { return ""; }
		void writeTake(JavaClass cw) {
			cw.codeln("	public void take(int type) throws Error { yy_wants(type, "+id+"); yyShift(yyfindShift(type)); }");
		}
		@Override
		void writeFinish(JavaClass cw) {
			cw.codeln("	public void finish() throws Error { yyfindShift(0); }");
		}
		
	}
}
